"""
Main PortScanner program

Scans Network computers for open ports.

"""


import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) # DON'T SHOW SCAPY WARNINGS
import sys
import os
import argparse
from support import getMyIPs
from support import scanner
from support import calculateIP
from support import portResult
import sqlite3
import hashlib
import gnupg


def main():
	"""Main Function"""
	parser = argparse.ArgumentParser(description='LPD PortScanner')
	parser.add_argument("interface",help="Interface with a valid IP to calculate the Subnet",)
	parser.add_argument("username",help="Username",)
	parser.add_argument("password",help="Username",)
	parser.add_argument("-k", "--knownports", help="Scans Target Subnet for open Known Ports",action="store_true")
	parser.add_argument("-r", "--reservedports", help="Scans Target Subnet for open Reserved Ports",action="store_true")
	parser.add_argument("-R", "--range", help="Scans Target Subnet for open ports in range. Example -R 8 80", type=int, nargs=2, metavar=('start', 'finish'))
	parser.add_argument("-l", "--list", help="Scans Target Subnet for open ports present in a list. Example -l 1,4,5,7", default='')
	parser.add_argument("-a", "--allports", help="Scans Target Subnet for All open ports. This Overides the previous options",action="store_true")
	parser.add_argument("-csv", "--csv", help="directs output to CSV FIle",default = '' , nargs=1,metavar=('CSV File Location'))

	args = parser.parse_args()
	interface = args.interface
	
	gpg=gnupg.GPG(gnupghome="./keys")
	keyid = gpg.list_keys()[0]['keyid']
	
	#DECRYPT BD
	
	
	with open('login.dat', 'rb') as f:
		status = gpg.decrypt_file(f, passphrase='password', output='login.db')

	conn = sqlite3.connect("login.db")
	cursor = conn.cursor()
	sql = "SELECT * FROM users WHERE username=?"
	cursor.execute(sql, [args.username])
	m = hashlib.md5()
	m.update(args.password)

	result = cursor.fetchall()
	if len(result) > 0:
		if (result[0][1] == m.hexdigest()):
			if (result[0][2] == '1'):
				print "Welcome " + args.username
			else:
				print "Username not active"
		else:
			print "Wrong Username and Password"
			os.remove('login.db')
			sys.exit()
	else:
		print "Wrong Username and Password"
		os.remove('login.db')
		sys.exit()

	os.remove('login.db')
	if args.csv == '':
		saveToFile = False
	else:
		saveToFile = True
		print saveToFile
		file = open(args.csv[0], "w")
		
		

	result = getMyIPs.getLocalIps()
	ip = ''
	mask = ''
	for x in result:
		if (x.interfaceName == interface):
			ip = x.ipAddress
			mask = x.netmask
			
	if ip == '':
		print 'Error: Selected interface doesn\'t have a valid IP Address. Valid Interfaces:'
		for x in result:
			print x
		sys.exit()

	ports = []	
	if args.knownports:
		ports = ports + [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 33, 35, 37, 39, 40, 42, 43, 47, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 64, 67, 68, 69, 70, 71, 72, 73, 74, 79, 80, 81, 82, 88, 90, 99, 100, 101, 102, 104, 105, 107, 108, 109, 110, 111, 113, 115, 117, 118, 119, 123, 126, 135, 137, 138, 139, 143, 152, 153, 156, 158, 161, 162, 170, 175, 177, 179, 194, 199, 201, 209, 210, 213, 218, 220, 259, 264, 280, 308, 311, 318, 319, 320, 350, 351, 366, 369, 370, 371, 383, 384, 387, 389, 399, 401, 427, 443, 444, 445, 464, 465, 475, 497, 500, 502, 504, 512, 513, 514, 515, 517, 518, 520, 524, 525, 530, 531, 532, 533, 540, 542, 543, 544, 545, 546, 547, 548, 550, 554, 556, 560, 561, 563, 587, 591, 593, 604, 623, 631, 635, 636, 639, 641, 646, 647, 648, 651, 653, 654, 657, 660, 666, 674, 688, 691, 694, 695, 698, 700, 701, 702, 706, 711, 712, 749, 750, 751, 752, 753, 754, 760, 782, 783, 808, 829, 843, 847, 848, 860, 861, 862, 873, 888, 897, 898, 901, 902, 903, 904, 911, 944, 953, 973, 981, 987, 989, 990, 991, 992, 993, 995, 999, 1002, 1023]
	if args.reservedports:
		ports = ports + [1024, 1025, 1026, 1029, 1058, 1059, 1080, 1085, 1098, 1099, 1109, 1110, 1140, 1167, 1169, 1176, 1182, 1194, 1198, 1200, 1214, 1217, 1220, 1223, 1232, 1234, 1236, 1241, 1270, 1293, 1301, 1309, 1311, 1313, 1314, 1319, 1337, 1344, 1352, 1387, 1414, 1417, 1418, 1419, 1420, 1431, 1433, 1434, 1470, 1494, 1500, 1501, 1503, 1512, 1513, 1521, 1524, 1526, 1527, 1533, 1534, 1547, 1550, 1581, 1589, 1590, 1627, 1645, 1646, 1666, 1677, 1688, 1700, 1701, 1707, 1716, 1719, 1720, 1723, 1725, 1755, 1761, 1762, 1768, 1776, 1792, 1801, 1812, 1813, 1863, 1883, 1886, 1900, 1920, 1935, 1947, 1967, 1970, 1971, 1972, 1975, 1977, 1984, 1985, 1994, 1997, 1998, 2000, 2001, 2002, 2010, 2030, 2031, 2041, 2049, 2053, 2056, 2074, 2080, 2082, 2083, 2086, 2087, 2095, 2096, 2102, 2103, 2104, 2105, 2115, 2121, 2144, 2145, 2156, 2160, 2161, 2181, 2190, 2195, 2196, 2200, 2210, 2211, 2212, 2219, 2220, 2221, 2222, 2223, 2261, 2262, 2301, 2302, 2303, 2305, 2323, 2369, 2370, 2379, 2381, 2399, 2401, 2404, 2420, 2424, 2427, 2447, 2463, 2480, 2483, 2484, 2500, 2501, 2518, 2525, 2535, 2546, 2593, 2598, 2599, 2610, 2612, 2636, 2638, 2641, 2642, 2698, 2700, 2710, 2735, 2800, 2809, 2827, 2868, 2944, 2945, 2947, 2948, 2949, 2967, 3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3017, 3025, 3030, 3040, 3050, 3051, 3052, 3074, 3100, 3101, 3119, 3128, 3162, 3225, 3233, 3235, 3260, 3268, 3269, 3283, 3299, 3300, 3305, 3306, 3313, 3333, 3386, 3389, 3396, 3412, 3423, 3424, 3455, 3478, 3483, 3516, 3527, 3535, 3537, 3544, 3605, 3606, 3632, 3689, 3690, 3702, 3723, 3724, 3784, 3785, 3799, 3800, 3825, 3826, 3835, 3868, 3872, 3880, 3899, 3900, 3945, 3978, 3979, 3999, 4000, 4001, 4007, 4018, 4035, 4045, 4069, 4089, 4093, 4096, 4100, 4105, 4111, 4116, 4125, 4172, 4201, 4224, 4226, 4242, 4321, 4323, 4433, 4436, 4444, 4445, 4486, 4500, 4502, 4534, 4567, 4569, 4610, 4640, 4662, 4664, 4672, 4711, 4712, 4713, 4728, 4732, 4747, 4750, 4753, 4840, 4843, 4847, 4894, 4899, 4949, 4950, 4982, 4993, 5000, 5001, 5002, 5003, 5004, 5005, 5010, 5011, 5029, 5031, 5037, 5050, 5051, 5060, 5061, 5070, 5082, 5083, 5084, 5085, 5093, 5099, 5104, 5106, 5107, 5108, 5109, 5110, 5121, 5124, 5125, 5150, 5151, 5154, 5176, 5190, 5222, 5223, 5228, 5246, 5247, 5269, 5280, 5281, 5298, 5310, 5311, 5312, 5313, 5314, 5315, 5349, 5351, 5353, 5355, 5357, 5358, 5394, 5402, 5405, 5412, 5413, 5421, 5432, 5433, 5445, 5450, 5457, 5458, 5495, 5498, 5499, 5500, 5501, 5517, 5550, 5555, 5556, 5591, 5631, 5632, 5656, 5666, 5667, 5678, 5721, 5723, 5741, 5742, 5800, 5814, 5850, 5852, 5900, 5912, 5938, 5984, 5999, 6000, 6001, 6005, 6009, 6050, 6051, 6072, 6086, 6100, 6101, 6110, 6111, 6112, 6113, 6129, 6257, 6260, 6262, 6324, 6343, 6346, 6347, 6350, 6389, 6432, 6444, 6445, 6502, 6503, 6514, 6515, 6522, 6523, 6543, 6560, 6561, 6566, 6571, 6600, 6619, 6646, 6660, 6664, 6665, 6669, 6679, 6697, 6699, 6702, 6715, 6771, 6789, 6881, 6887, 6888, 6889, 6890, 6891, 6900, 6901, 6902, 6968, 6969, 6970, 6999, 7000, 7001, 7002, 7005, 7006, 7010, 7022, 7023, 7025, 7047, 7133, 7144, 7145, 7171, 7306, 7307, 7312, 7396, 7400, 7401, 7402, 7473, 7547, 7615, 7624, 7634, 7652, 7654, 7655, 7656, 7660, 7670, 7676, 7700, 7707, 7708, 7717, 7777, 7778, 7787, 7788, 7831, 7880, 7890, 7915, 7935, 7937, 8000, 8001, 8002, 8008, 8009, 8010, 8011, 8013, 8014, 8020, 8042, 8069, 8070, 8074, 8075, 8078, 8080, 8081, 8086, 8087, 8088, 8089, 8090, 8100, 8111, 8116, 8118, 8123, 8192, 8193, 8194, 8195, 8200, 8222, 8243, 8280, 8291, 8303, 8331, 8332, 8333, 8400, 8442, 8443, 8484, 8500, 8501, 8601, 8602, 8642, 8691, 8701, 8702, 8767, 8768, 8778, 8834, 8840, 8880, 8881, 8882, 8883, 8886, 8887, 8888, 8889, 8983, 8998, 9000, 9001, 9009, 9010, 9020, 9025, 9030, 9043, 9050, 9051, 9060, 9080, 9090, 9091, 9100, 9101, 9102, 9103, 9105, 9106, 9107, 9110, 9119, 9191, 9199, 9293, 9300, 9303, 9306, 9309, 9312, 9418, 9420, 9421, 9422, 9535, 9536, 9600, 9675, 9676, 9695, 9800, 9875, 9898, 9936, 9987, 9996, 9998, 9999, 10000, 10001, 10008, 10009, 10010, 10017, 10024, 10025, 10050, 10051, 10110, 10113, 10114, 10115, 10116, 10172, 10200, 10201, 10204, 10301, 10302, 10308, 10480, 10823, 10891, 11001, 11155, 11211, 11235, 11294, 11371, 11576, 12010, 12011, 12012, 12013, 12035, 12201, 12222, 12223, 12345, 12489, 12975, 12998, 12999, 13000, 13008, 13050, 13075, 13195, 13196, 13337, 13340, 13720, 13721, 13724, 13782, 13783, 13785, 13786, 14439, 14567, 14900, 15000, 15345, 15556, 15567, 16000, 16080, 16200, 16250, 16384, 16567, 17500, 18010, 18104, 18180, 18200, 18201, 18206, 18300, 18301, 18306, 18333, 18400, 18401, 18505, 18506, 18605, 18606, 19000, 19001, 19226, 19283, 19294, 19295, 19302, 19315, 19540, 19638, 19812, 19813, 19814, 19999, 20000, 20014, 20560, 20702, 20720, 20790, 21001, 21011, 21012, 21021, 21022, 22136, 22222, 22347, 22349, 22350, 23073, 23399, 23513, 24444, 24465, 24554, 24800, 24842, 25000, 25003, 25005, 25007, 25010, 25560, 25565, 25570, 25826, 25888, 25999, 26000, 26850, 26900, 26901, 27000, 27009, 27010, 27014, 27015, 27016, 27017, 27030, 27050, 27374, 27500, 27888, 27900, 27901, 27910, 27950, 27960, 27969, 28000, 28001, 28395, 28785, 28786, 28852, 28910, 28960, 29000, 29070, 29292, 29900, 29901, 29920, 30000, 30301, 30564, 30718, 30777, 31314, 31337, 31415, 31456, 31457, 31458, 31620, 32123, 32137, 32245, 32769, 32887, 32976, 33434, 33982, 34443, 34567, 36330, 36963, 37659, 37777, 40000, 40123, 41823, 43034, 43047, 43048, 43594, 43595, 44405, 45824, 47001, 47808, 49151, 55901]
	if args.list != '':
		try:
			ports = ports + [int(x) for x in args.list.split(",")]
		except (ValueError, AttributeError, TypeError):
			print 'Error Parsing Port List - Invalid Argument: ' + args.list
			sys.exit()
	if args.range:
			ports = ports + [int(x) for x in range(args.range[0],args.range[1])]
	if args.allports:
		ports = range(1,65535)


	ports = sorted(set(ports))
	print "Interface: " + interface
	print "IP: " + ip
	print "Netmask: " + mask + "\n"	
	print "Total number of Ports to scan: " + str(len(ports)) + " ports\n"
		
	ipCalculator = calculateIP.CalculateIp(ip,mask)
	ipCalculator.calculate()

	listaPortScan = []
	scan = scanner.PortScan('',ports,80)
	for x in ipCalculator.ipList:
		scan.setIp(x)
		openports,closedports = scan.scanports()
		if not(len(openports) == 0 & len(closedports) == 0):
			listaPortScan.append(portResult.portResult(x,openports,closedports))

	print "Port Scan Results:"

	for x in listaPortScan:
		if saveToFile:
			file.write(x.ip + ';' + str(x.openPorts) + ';' + str(x.closedPorts) + '\n' )
		else:
			print x
	
	if saveToFile:	
		file.close()
	
if  __name__ =='__main__':main()
